package com.hx.app.leetcode.com.hx.addtwonumbers;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author hx 2022/7/3 10:43
 */
public class AddTwoNumbers {
    public static void main(String[] args) {
        Solution solution = new Solution();
        // int[] i1 = {2,4,3};
        // int[] i2 = {5,6,4};
        // int[] i1 = {0};
        // int[] i2 = {0};
        int[] i1 = {9, 9, 9, 9, 9, 9, 9};
        int[] i2 = {9, 9, 9, 9};
        ListNode listNode1 = solution.array2ListNode(i1);
        ListNode listNode2 = solution.array2ListNode(i2);

        ListNode listNode = solution.addTwoNumbers(listNode1, listNode2);
        System.out.println(solution.toList(listNode));
    }
}

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    /**
     * 暴力解法
     *
     * @param l1
     * @param l2
     * @return
     */
    /*public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        l1 = reverse(l1);
        l2 = reverse(l2);

        BigDecimal b1 = toNum(l1);
        BigDecimal b2 = toNum(l2);
        BigDecimal add = b1.add(b2);
        String[] strings = add.toString().split("");

        int[] nums = new int[strings.length];
        for (int i = 0; i < strings.length; i++) {
            nums[i] = Integer.parseInt(strings[i]);
        }

        return reverse(array2ListNode(nums));
    }*/
    /*public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        List<Integer> nums1 = toList(l1);
        List<Integer> nums2 = toList(l2);
        int length = Math.max(nums1.size(), nums2.size());
        int temp = 0;
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < length; i++) {
            Integer i1 = i < nums1.size() ? nums1.get(i) : 0;
            Integer i2 = i < nums2.size() ? nums2.get(i) : 0;

            int i3 = i1 + i2 + temp;
            if (i3 >= 10) {
                temp = 1;
                res.add(i3 % 10);
            } else {
                temp = 0;
                res.add(i3);
            }
        }
        if (temp != 0) {
            res.add(temp);
        }

        return array2ListNode(res.stream().mapToInt(Integer::intValue).toArray());
    }*/

    public List<Integer> toList(ListNode listNode) {
        List<Integer> list = new ArrayList<>();
        if (listNode != null) {
            list.add(listNode.val);
            ListNode next = listNode.next;
            while (next != null) {
                list.add(next.val);
                next = next.next;
            }
        }
        return list;
    }

    public ListNode array2ListNode(int[] arr) {

        ListNode head = new ListNode(arr[0]);

        ListNode listNode = head;
        for (int i = 1; i < arr.length; i++) {
            ListNode next = new ListNode(arr[i]);
            listNode.next = next;
            listNode = next;
        }
        return head;
    }

    public ListNode reverse(ListNode listNode) {
        if (listNode != null && listNode.next != null) {

            ListNode first = null;
            while (listNode != null) {

                ListNode next = listNode.next;

                listNode.next = first;
                first = listNode;
                listNode = next;
            }
            return first;
        }
        return listNode;
    }

    public BigDecimal toNum(ListNode listNode) {
        ListNode next = listNode.next;
        StringBuilder builder = new StringBuilder();
        builder.append(listNode.val);
        while (next != null) {
            builder.append(next.val);
            next = next.next;
        }
        return new BigDecimal(builder.toString());
    }
    /*public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int[] nums1 = toArray(l1);
        int[] nums2 = toArray(l2);
        int length = Math.max(nums1.length, nums2.length);
        int temp = 0;
        int[] res = new int[length];
        int i = 0;
        for (; i < length; i++) {
            int i1 = i < nums1.length ? nums1[i] : 0;
            int i2 = i < nums2.length ? nums2[i] : 0;

            int i3 = i1 + i2 + temp;
            if (i3 >= 10) {
                temp = 1;
                res[i] = (i3 % 10);
            } else {
                temp = 0;
                res[i] = i3;
            }
        }
        if (temp != 0) {
            res = Arrays.copyOf(res, length+1);
            res[i] = temp;
        }

        return array2ListNode(res);
    }*/

    public int[] toArray(ListNode listNode) {
        int length = 1;
        int[] nums = new int[length];
        if (listNode != null) {
            int i = 0;
            nums[i++] = listNode.val;
            ListNode next = listNode.next;
            while (next != null) {
                if (i == length) {
                    nums = Arrays.copyOf(nums, ++length);
                }
                nums[i++] = next.val;
                next = next.next;
            }
        }
        return nums;
    }
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummyHead = new ListNode(-1), pre = dummyHead;
        int t = 0;
        while (l1 != null || l2 != null || t != 0) {
            if (l1 != null) {
                t += l1.val;
                l1 = l1.next;
            }
            if (l2 != null) {
                t += l2.val;
                l2 = l2.next;
            }
            pre.next = new ListNode(t % 10);
            pre = pre.next;
            t /= 10;
        }

        return dummyHead.next;
    }
}

class ListNode {
    int val;
    ListNode next;

    ListNode() {
    }

    ListNode(int val) {
        this.val = val;
    }

    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}